import type { DirectiveBinding } from 'vue'

interface ScrollElement extends HTMLElement {
  timer?: NodeJS.Timer
  hoverStop?: boolean
  // 添加存储当前数据的字段
  currentData?: any[]
}

interface ScrollOptions {
  step?: number
  interval?: number
  hoverStop?: boolean
  // 添加自定义数据参数
  data?: any[]
}

function initScroll(el: ScrollElement, binding: DirectiveBinding<ScrollOptions>) {
  const scrollBox = el
  const scrollContent = el.children[0] as HTMLElement
  const options = binding.value || {}

  // 停止当前定时器
  el.timer && clearInterval(el.timer)

  // 完全重置DOM状态
  scrollBox.scrollTop = 0
  scrollContent.style.transform = 'translateY(0)'
  scrollContent.style.transition = 'none'

  // 强制重绘
  void scrollContent.offsetHeight

  // 恢复平滑滚动
  scrollContent.style.transition = ''

  // 存储当前数据
  el.currentData = options.data ? [...options.data] : undefined

  const step = options.step || 50
  const interval = options.interval || 3000
  const hoverStop = options.hoverStop ?? true

  const scroll = () => {
    if (scrollContent.offsetHeight > scrollBox.offsetHeight) {
      let scrollTop = scrollBox.scrollTop
      if (scrollTop >= scrollContent.offsetHeight - scrollBox.offsetHeight) {
        scrollBox.scrollTop = 0
      } else {
        scrollBox.scrollTo({
          top: scrollTop + step,
          behavior: 'smooth'
        })
      }
    }
  }

  const startScroll = () => {
    el.timer = setInterval(scroll, interval)
  }

  const stopScroll = () => {
    el.timer && clearInterval(el.timer)
  }

  if (hoverStop) {
    scrollBox.addEventListener('mouseenter', stopScroll)
    scrollBox.addEventListener('mouseleave', startScroll)
  }

  startScroll()
  el.hoverStop = hoverStop
}

export default {
  mounted(el: ScrollElement, binding: DirectiveBinding<ScrollOptions>) {
    initScroll(el, binding)
  },

  updated(el: ScrollElement, binding: DirectiveBinding<ScrollOptions>) {
    // 当data数据变化时重新初始化
    if (JSON.stringify(el.currentData) !== JSON.stringify(binding.value.data)) {
      // 直接调用initScroll，它内部会处理定时器
      setTimeout(() => initScroll(el, binding), 50)
    }
  },

  unmounted(el: ScrollElement) {
    el.timer && clearInterval(el.timer)
    if (el.hoverStop) {
      el.removeEventListener('mouseenter', () => { })
      el.removeEventListener('mouseleave', () => { })
    }
  }
}